﻿using System;
using System.Collections.Generic;

namespace Sustainalytics.ESGRatings.BusinessLogic.Computing
{
    public class RatingsResult : IDisposable
    {
        BufferManager manager;

        public RatingsResult() { }

        public RatingsResult(BufferManager manager, int companiesCount, int indicatorsCount, int clustersCount, int clusterGroupsCount, bool computeIndicatorRatings, bool includeAggregatedWeights, bool includeWeights, bool isDefaultWeightMatrix = false)
        {
            this.manager = manager;
            CompaniesCount = companiesCount;
            ClustersCount = clustersCount;
            IndicatorsCount = indicatorsCount;
            ClusterGroupsCount = clusterGroupsCount;

            TimedSteps = new List<TimedStep>();


            ComputeIndicatorsRatings = computeIndicatorRatings;
            ComputeAggregatedWeights = includeAggregatedWeights;
            IncludeWeights = includeWeights;
            IsDefaultWeightMatrix = isDefaultWeightMatrix;
        }

        public bool ComputeIndicatorsRatings { get; set; }
        public bool ComputeAggregatedWeights { get; set; }
        public bool IncludeWeights { get; set; }
        public bool IsDefaultWeightMatrix { get; set; }

        public void AllocateBuffers()
        {
            Ratings = manager.Get<float>(CompaniesCount * ClustersCount);
            CompanyIndices = manager.Get<int>(CompaniesCount * ClustersCount);
            IsInReferenceUniverse = manager.Get<bool>(CompaniesCount);

            if (ComputeIndicatorsRatings)
                IndicatorsRatings = manager.Get<float>(CompaniesCount * IndicatorsCount);

            if (ComputeAggregatedWeights)
                AggregatedWeights = manager.Get<float>(CompaniesCount * ClustersCount);

            if (IncludeWeights)
                Weights = manager.Get<float>(CompaniesCount * IndicatorsCount);

            Rankings = manager.Get<int>(CompaniesCount * ClustersCount);
            Percentile = manager.Get<float>(CompaniesCount * ClustersCount);
            Group_Counts = manager.Get<int>(CompaniesCount * ClustersCount);

            Group_Avgs = manager.Get<float>(ClusterGroupsCount * ClustersCount);
            Group_Mins = manager.Get<float>(ClusterGroupsCount * ClustersCount);
            Group_Maxs = manager.Get<float>(ClusterGroupsCount * ClustersCount);

        }


        public int CompaniesCount;
        public int ClustersCount;
        public int IndicatorsCount;

        public float[] Ratings;
        public float[] IndicatorsRatings;
        public float[] AggregatedWeights;
        public float[] Weights;
        public int[] CompanyIndices;
        public bool[] IsInReferenceUniverse;
        public float[] Percentile;

        public int[] Rankings;
        public int ClusterGroupsCount;
        public float[] Group_Mins;
        public float[] Group_Maxs;
        public float[] Group_Avgs;
        public int[] Group_Counts;

        private bool _disposed = false;

        public void Dispose()
        {
            if (_disposed)
                return;

            _disposed = true;

            if (Ratings != null)
                manager.Release(Ratings);

            if (CompanyIndices != null)
                manager.Release(CompanyIndices);

            if (IndicatorsRatings != null)
                manager.Release(IndicatorsRatings);

            if (IsInReferenceUniverse != null)
                manager.Release(IsInReferenceUniverse);

            Ratings = null;
            CompanyIndices = null;
            IsInReferenceUniverse = null;
            IndicatorsRatings = null;
            AggregatedWeights = null;
            Weights = null;
            Percentile = null;
        }


        public List<TimedStep> TimedSteps { get; protected set; }

    }
}
